package com.kehutong.contact.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;
import com.kehutong.common.DoveClient;
import com.kehutong.common.Java8TimeUtils;
import com.kehutong.common.dto.UniformSendReqDto;
import com.kehutong.common.enums.HouseType;
import com.kehutong.common.enums.MessageBusinessEnum;
import com.kehutong.common.enums.OperateType;
import com.kehutong.common.enums.TemplateType;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.urlconfig.WebUrlConfig;
import com.kehutong.common.util.TemplateReplaceUtil;
import com.kehutong.common.util.Token;
import com.kehutong.contact.entity.ResidentHouse;
import com.kehutong.contact.entity.ResidentHouseBindApply;
import com.kehutong.contact.entity.UserApplyCompany;
import com.kehutong.contact.enums.AuditStatus;
import com.kehutong.contact.enums.ResidentType;
import com.kehutong.contact.service.ResidentService;
import com.kehutong.contact.util.ResidentUtil;

/**
 * @author: liukunlong
 * @date: 2021-04-04 11:41
 */
@WebService("/crm/resident/house/bind/service")
public class ResidentHouseBindApplyService {
    static final Logger logger = LoggerFactory.getLogger(ResidentHouseBindApplyService.class);

    @Inject
    private DoveClient doveClient;

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private ResidentService residentService;

    @Inject
    private WebUrlConfig webUrlConfig;

    @ReqMapping("/lastApplyCompanyNo")
    public Object getUserLastApply(String uuid) throws Exception {
        UserApplyCompany userApplyCompany = jdbcSession.findById(UserApplyCompany.class, uuid);
        if (userApplyCompany != null) {
            return userApplyCompany.getCompanyNo();
        }
        return null;
    }

    /**
     * 根据条件微信房屋绑定申请列表
     *
     * @param jsonObject 查询条件
     * @return 微信房屋绑定申请列表
     * @throws Exception 异常
     */
    @ReqMapping("/list")
    public Object getResidentHouseBindApplyList(Token token, JSONObject jsonObject) throws Exception {
        Page<ResidentHouseBindApply> result = null;
        FindPage<ResidentHouseBindApply> find = jdbcSession.findPage(ResidentHouseBindApply.class)
                .eq(jsonObject, "id", "realname", "mobile", "auditNo", "houseNo","type","residentNo")
                .eq("deleted", 0)
                .in(jsonObject,"status")
                .between("createTime", jsonObject, "beginTime", "endTime")
                .order("createTime", "desc")
                .page(jsonObject);
        result = find.exe();
        return result;
    }

    /**
     * 管家端或管理后台触发
     *
     * 审核微信房屋绑定申请
     * 1.审核通过增加客户通业主信息
     * 2.增加住户编号房屋绑定信息
     * 3.回写住户编号信息的手机号与真实姓名,并且设置住户编号绑定过会员
     *
     * @param residentHouseBindApply 微信房屋绑定申请对象
     * @return 操作结果
     * @throws Exception 异常
     */
    @Bean(copy = true)
    @ReqMapping("/audit")
    public Object auditResidentHouseBindApply(ResidentHouseBindApply residentHouseBindApply) throws Exception {
        jdbcSession.updateById(residentHouseBindApply);
        //0 待审核 1审核中 2审核通过 3.审核不通过
        AuditStatus status = residentHouseBindApply.getStatus();
        //审核通过增加客户通业主信息,增加绑定信息
        logger.info("---------------------审核状态status=" + status.getId());
        if (Objects.equal(status.getId(), AuditStatus.PassAudit.getId())) {
           residentService.bindResidentHouse(residentHouseBindApply);
            //TODO 消息提醒,审核通过
            // 发送给业主/租客/家属等
            try {
                //新增客户轨迹
                doveClient.post("/auth/accountOperateLog/service/add", (http) -> {
                    JSONObject body = new JSONObject();
                    body.put("accountNo",residentHouseBindApply.getResidentNo());
                    if (Objects.equal(HouseType.HOUSE.getId(), residentHouseBindApply.getHouseType().getId())) {
                        body.put("type", OperateType.ADD_RESIDENT.getId());
                        if(Objects.equal(ResidentType.OWNER.getId(),residentHouseBindApply.getType().getId())){
                            body.put("desc", "新增房屋业主");
                        }else if(Objects.equal(ResidentType.FRIEND.getId(),residentHouseBindApply.getType().getId())){
                            body.put("desc", "新增房屋家属");
                        }else{
                            body.put("desc", "新增房屋租客");
                        }
                    } else if (Objects.equal(HouseType.SHOP.getId(), residentHouseBindApply.getHouseType().getId())) {
                        body.put("type", OperateType.ADD_SHOP_USER.getId());
                        body.put("desc", "新增商铺业主");
                    } else if (Objects.equal(HouseType.PARKING.getId(), residentHouseBindApply.getHouseType().getId())) {
                        body.put("type", OperateType.ADD_PARKING_USER);
                        body.put("desc", "新增车位业主");
                    }
                    body.put("createBy", residentHouseBindApply.getAuditNo());
                    body.put("createName", residentHouseBindApply.getAuditName());
                    body.put("companyNo",residentHouseBindApply.getCompanyNo());
                    body.put("companyName","");
                    http.setBody(body.toJSONString());
                });
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

            try {
                // 用户false
                logger.info("=============================发送消息");
                msgUniformSend(residentHouseBindApply, residentHouseBindApply.getResidentNo(), true, TemplateType.RESIDENT_C_AUDIT_SUCCESS, Arrays.asList(residentHouseBindApply.getMobile()));
                // 管家  遍历
                Set<String> managerIdList = ResidentUtil.getManagerIdList(residentHouseBindApply.getBuildNo(), residentHouseBindApply.getHouseType().getId());
                for (String each : managerIdList) {
                    msgUniformSend(residentHouseBindApply, each, false, TemplateType.RESIDENT_B_ADD);
                }
            } catch (Exception e) {
                logger.error("发送消息："+e.getMessage(), e);
            }
        } else {
            //TODO 消息提醒,审核不通过
            try {
                msgUniformSend(residentHouseBindApply, residentHouseBindApply.getResidentNo(), true, TemplateType.RESIDENT_C_AUDIT_FAIL, Arrays.asList(residentHouseBindApply.getMobile()));
            } catch (Exception e) {
                logger.error("发送消息："+e.getMessage(), e);
            }
        }
        return Result.success();
    }

    private void msgUniformSend(ResidentHouseBindApply apply, String uuid, boolean userCreate, TemplateType templateType) throws Exception {
        msgUniformSend(apply, uuid, userCreate, templateType, null);
    }

    private void msgUniformSend(ResidentHouseBindApply apply, String uuid, boolean userCreate, TemplateType templateType, List<String> phoneList) throws Exception {
        // 获取消息推送配置文件
        JSONObject configJson = doveClient.post("/crm/message/global/config/service/get", (http) -> {
            http.addParam("templateType", templateType.getId());
        });

        if (configJson.getIntValue("code") == 200) {
            UniformSendReqDto dto = getUniformSendReqDto(apply, uuid, userCreate, templateType, phoneList, configJson.getJSONObject("data"));
            // 消息推送
            doveClient.post("/crm/message/service/uniformSend", (http) -> {
                http.addParam("temp", JSONObject.toJSONString(dto));
            });
        }
    }

    private UniformSendReqDto getUniformSendReqDto(ResidentHouseBindApply apply, String uuid, boolean userCreate, TemplateType templateType, List<String> phoneList, JSONObject dataJson) throws Exception {
        logger.info("service.msgUniformSend.apply参数：{}", apply.toString());
        UniformSendReqDto dto = new UniformSendReqDto();
        if (TemplateType.RESIDENT_B_ADD == templateType){
            dto.setMsgId(apply.getResidentNo());
        } else {
            dto.setMsgId(apply.getId());
        }
        dto.setBusinessTypeId(MessageBusinessEnum.MSG_RESIDENT.getId());
        dto.setTemplateTypeId(templateType.getId());
        dto.setCompanyNo(apply.getCompanyNo());
        dto.setUserCreate(userCreate);
        dto.setUuid(uuid);
        dto.setTitle("住户消息");

        JSONObject inner = dataJson.getJSONObject("messageTemplateInner");
        if (dataJson.getBooleanValue("innerSend") && Objects.nonNull(inner)) {
            dto.setTitle(inner.getString("title"));
            dto.setInnerData(TemplateReplaceUtil.replace(inner.getString("content"), inner.getString("tagArray"), apply));
        }

        JSONObject app = dataJson.getJSONObject("messageTemplateApp");
        if (dataJson.getBooleanValue("appSend") && Objects.nonNull(app)) {
            dto.setTitle(app.getString("title"));
            dto.setAppData(TemplateReplaceUtil.replace(app.getString("content"), app.getString("tagArray"), apply));
            if (TemplateType.RESIDENT_B_ADD == templateType){
                dto.setAppToUrl(webUrlConfig.getUrl("/web-app/?page=resident/portrait/" + apply.getResidentNo()));
            } else {
                dto.setAppToUrl(webUrlConfig.getUrl("/web-app/?page=audit/" + apply.getId()));
            }
        }

        JSONObject sms = dataJson.getJSONObject("messageTemplateSms");
        if (dataJson.getBooleanValue("smsSend") && Objects.nonNull(sms)) {
            if (Objects.nonEmpty(phoneList)){
                dto.setPhoneList(phoneList);
                dto.setSmsDataParams(TemplateReplaceUtil.listTencentSmsParam(sms.getString("content"), sms.getString("tagArray"), apply));
            } else {
                JSONObject jsonObject = doveClient.post("/kht-bin/auth/user/listPhone", http -> {
                    JSONObject temp = new JSONObject();
                    temp.put("id", Arrays.asList(uuid));
                    http.setBody(temp.toJSONString());
                });
                List<String> listPhone = JSONArray.parseArray(jsonObject.getString("data"), String.class);
                if (Objects.nonEmpty(listPhone)){
                    dto.setPhoneList(listPhone);
                    dto.setSmsDataParams(TemplateReplaceUtil.listTencentSmsParam(sms.getString("content"), sms.getString("tagArray"), apply));
                }
            }
        }

        String wxchatTemplate = dataJson.getString("wxchatTemplate");
        if (dataJson.getBooleanValue("wxchatSend") && Objects.nonNull(wxchatTemplate)) {
            dto.setWxChatData(getWxchatTemplate(templateType, apply));
        }
        return dto;
    }

    private String getWxchatTemplate(TemplateType templateType, ResidentHouseBindApply apply){
        JSONObject data = new JSONObject();

        if(TemplateType.RESIDENT_C_AUDIT_SUCCESS == templateType){
            data.put("first", buildMpMessageData("您的住户申请已通过"));
            // 小区名称
            data.put("keyword1", buildMpMessageData(apply.getCommunityName()));
            // 房间号
            data.put("keyword2", buildMpMessageData(apply.getHouseName()));
            // 关系
            ResidentType type = apply.getType();
            if (type == ResidentType.OWNER) {
                data.put("keyword3", buildMpMessageData(ResidentType.OWNER.getDesc()));
            } else if (type == ResidentType.FRIEND) {
                data.put("keyword3", buildMpMessageData(ResidentType.FRIEND.getDesc()));
            } else {
                data.put("keyword3", buildMpMessageData(ResidentType.LESSEE.getDesc()));
            }


            data.put("remark", buildMpMessageData("祝您生活愉快！"));
            return data.toJSONString();
        } else if (TemplateType.RESIDENT_C_AUDIT_FAIL == templateType) {
            data.put("first", buildMpMessageData("您的住户申请未通过"));
            // 审核状态
            data.put("keyword1", buildMpMessageData(apply.getStatus().getDesc()));
            // 审核时间
            data.put("keyword2", buildMpMessageData(Java8TimeUtils.parseString(apply.getAuditTime())));
            // 不通过原因
            data.put("keyword3", buildMpMessageData(apply.getAuditRemarks()));

            data.put("remark", buildMpMessageData("若有疑问请拨打物业电话~"));
            return data.toJSONString();
        } else {
            return null;
        }
    }

    private JSONObject buildMpMessageData(String value) {
        JSONObject json = new JSONObject();
        json.put("value", value);
        return json;
    }

    /**
     * 构建微信绑定的房屋信息
     *
     * @param residentHouseBindApply 微信房屋绑定申请
     * @return 微信绑定的房屋信息
     */
    ResidentHouse buildResidentHouse(ResidentHouseBindApply residentHouseBindApply) {
        ResidentHouse residentHouse = Pool.newInstance(ResidentHouse.class);
        //住户编号编号
        residentHouse.setResidentNo(residentHouseBindApply.getResidentNo());
        //小区编号
        residentHouse.setCommunityNo(residentHouseBindApply.getCommunityNo());
        //小区名称
        residentHouse.setCommunityName(residentHouseBindApply.getCommunityName());
        residentHouse.setCommunityViewName(residentHouseBindApply.getCommunityViewName());
        //楼栋编号
        residentHouse.setBuildNo(residentHouseBindApply.getBuildNo());
        //楼栋名称
        residentHouse.setBuildName(residentHouseBindApply.getBuildName());
        residentHouse.setBuildViewName(residentHouseBindApply.getBuildViewName());

        //单元名称
        residentHouse.setUnitName(residentHouseBindApply.getUnitName());
        //楼层名称
        residentHouse.setFloorName(residentHouseBindApply.getFloorName());
        //房屋编号
        residentHouse.setHouseNo(residentHouseBindApply.getHouseNo());
        //房屋名称
        residentHouse.setHouseName(residentHouseBindApply.getHouseName());
        residentHouse.setHouseViewName(residentHouseBindApply.getHouseViewName());
        //住户身份
        residentHouse.setType(residentHouseBindApply.getType());

        //租赁开始时间
        residentHouse.setStartTime(residentHouseBindApply.getStartTime());

        //租赁结束时间
        residentHouse.setEndTime(residentHouseBindApply.getEndTime());
        return residentHouse;
    }
}
